package com.ruoyi.vod.service.impl;

import com.aliyun.vod.upload.impl.UploadVideoImpl;
import com.aliyun.vod.upload.req.UploadStreamRequest;
import com.aliyun.vod.upload.resp.UploadStreamResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.vod.model.v20170321.DeleteVideoRequest;
import com.aliyuncs.vod.model.v20170321.GetVideoPlayAuthRequest;
import com.aliyuncs.vod.model.v20170321.GetVideoPlayAuthResponse;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.vod.service.VodService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.InputStream;

/**
 * @author Alex
 */
@Service
public class VodServiceImpl implements VodService {

    public static final String REGION_ID = "cn-shanghai";
    public static final String ACCESS_KEY_ID = "LTAI5tBYczBbYuPzejZY7m9p";
    public static final String ACCESS_KEY_SECRET = "oy6PkkJtYufKFqh50TR0zBCGZKDGdU";
    public static final String ADMIN_VIEW = "0";

    @Resource
    private RedisService redisService;

    /**
     * 上传视频到阿里云
     *
     * @param file 视频文件
     * @return 上传后的视频ID
     */
    @Override
    public String uploadVideo(MultipartFile file) {
        try {
            //fileName：上传文件原始名称
            String fileName = file.getOriginalFilename();
            //title：上传之后显示名称
            String title = fileName == null ? "未命名文件" : fileName.substring(0, fileName.lastIndexOf("."));
            //inputStream：上传文件输入流
            InputStream inputStream = file.getInputStream();
            UploadStreamRequest request = new UploadStreamRequest(ACCESS_KEY_ID, ACCESS_KEY_SECRET, title, fileName, inputStream);
            UploadVideoImpl uploader = new UploadVideoImpl();
            UploadStreamResponse response = uploader.uploadStream(request);
            String videoId;
            if (response.isSuccess()) {
                videoId = response.getVideoId();
            } else { //如果设置回调URL无效，不影响视频上传，可以返回VideoId同时会返回错误码。其他情况上传失败时，VideoId为空，此时需要根据返回错误码分析具体错误原因
                return null;
            }
            return videoId;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public boolean removeVideo(String id) {
        try {
            //初始化对象
            DefaultAcsClient client = new DefaultAcsClient(DefaultProfile.getProfile(REGION_ID, ACCESS_KEY_ID, ACCESS_KEY_SECRET));
            //创建删除视频的request对象
            DeleteVideoRequest request = new DeleteVideoRequest();
            //向request设置删除的视频id
            request.setVideoIds(id);
            client.getAcsResponse(request);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public String getPlayAuth(String courseId, String videoResourceId) {
        try {
            //1.初始化对象client
            DefaultAcsClient client = new DefaultAcsClient(DefaultProfile.getProfile(REGION_ID, ACCESS_KEY_ID, ACCESS_KEY_SECRET));
            //2.创建获取凭证的request和resp对象
            GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
            //3.向req中设置视频id
            request.setVideoId(videoResourceId);
            //4.调用方法得到凭证
            GetVideoPlayAuthResponse response = client.getAcsResponse(request);
            //5.调用异步方法记录此次观看
            if (!ADMIN_VIEW.equals(courseId)) {
                // 如果不是管理员端预览视频，就记录此次观看，从而在定时任务中添加学习次数
                recordView(courseId);
            }
            return response.getPlayAuth();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 每当会员观看视频时，给课程学习数加1
     * -> Redis记录，异步方法每5分钟执行一次，统计观看量并更新数据库
     *
     * @param courseId 被观看的课程id
     */
    @Async
    public void recordView(String courseId) {
        /* 直接以videoResourceId为键记录观看次数 */
        // 如果5分钟内已经有该视频的观看次数，则在原本基础上加一即可
        if (redisService.cacheMapExists(CacheConstants.VIDEO_VIEWS, courseId)) {
            redisService.incrementCacheMapValue(CacheConstants.VIDEO_VIEWS, courseId, 1);
        } else {
            // 否则添加对该视频观看次数的缓存
            redisService.setCacheMapValue(CacheConstants.VIDEO_VIEWS, courseId, 1);
        }
    }
}